package com.bsj.travel.process.handle.service.bolt.handle;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.bsj.consumerQ.function.HandleRun;
import com.bsj.travel.cached.redis.RedisCached;
import com.bsj.travel.config.rocketmq.producer.BaseMqPushUtil;
import com.bsj.travel.constant.ActConstants;
import com.bsj.travel.constant.BaseServerTopicConstants;
import com.bsj.travel.constant.Constants;
import com.bsj.travel.def.common.DO.DeviceDO;
import com.bsj.travel.def.common.DTO.mqtt.EventAct;
import com.bsj.travel.def.common.VO.device.DeviceInfoVO;
import com.bsj.travel.def.global.mq.Rp;
import com.bsj.travel.mapper.mysql.DeviceMapper;
import com.bsj.travel.util.ExceptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author yinhao
 * @version 1.0
 * @description 行为状态变更实现类
 * @date 2024/2/20
 */
@Service
@Slf4j
public class BehaviorSaveHandleRun implements HandleRun {

    @Autowired
    private RedisCached redisCached;

    @Autowired
    private BaseMqPushUtil baseMqPushUtil;

    @Resource
    private DeviceMapper deviceMapper;

    @Override
    public void doRun(List<byte[]> list) {
        Map<String, List<DeviceDO>> updateMap = new HashMap<>();
        for (byte[] bytes : list) {
            try {
                String message = new String(bytes);
                EventAct event = JSON.parseObject(message, EventAct.class);
                String client = event.getEvent().getClient();
                String[] split = client.split("&");
                //设备号
                String deviceName = split[0];
                //产品key
                String productKey = split[1];
                int serveType = event.getServeType();
                //时间
                Date date = new Date();
                switch (serveType) {
                    // 上线/离线
                    case 2:
                        int state = 1;
                        //第一次上线需要更新设备的激活时间 || 更新设备上线时间
                        if (event.getOperate().equalsIgnoreCase(ActConstants.ONLINE)) {
                            state = 2;
                            DeviceDO deviceDO = redisCached.hgetDeviceInfo(productKey, deviceName);
                            if (deviceDO != null) {
                                Date gmtActive = deviceDO.getGmtActive();
                                if (gmtActive == null) {
                                    //更新激活时间
                                    deviceDO.setGmtActive(date);
                                    deviceDO.setTableName(Constants.DEVICE_TAB_STR + productKey);
                                    List<DeviceDO> deviceDOS = updateMap.get(productKey);
                                    if (deviceDOS == null) {
                                        deviceDOS = new ArrayList<>();
                                    }
                                    deviceDOS.add(deviceDO);
                                    updateMap.put(productKey, deviceDOS);
                                }
                                deviceDO.setGmtOnline(date.getTime() + "");

                                String ip = (String) event.getEvent().getData();
                                if (ip != null) {
                                    deviceDO.setIpAddress(ip);
                                }

                                redisCached.hsetDeviceInfo(productKey, deviceDO);
                            }
                        }
                        //设备状态变更通知
                        DeviceInfoVO vo = new DeviceInfoVO();
                        vo.setDeviceName(deviceName);
                        vo.setState(state);
                        Rp<DeviceInfoVO> rp = new Rp<>();
                        rp.setProductKey(productKey);
                        rp.setTag(BaseServerTopicConstants.DEVICE_STATE_CHANGE_TAG);
                        rp.setData(vo);
                        baseMqPushUtil.sendTopicBytes(BaseServerTopicConstants.PRODUCT_SUBSCRIBE_TOPIC,
                                BaseServerTopicConstants.DEVICE_STATE_CHANGE_TAG, JSON.toJSONBytes(rp));
                        break;
                    default:
                        log.warn("行为状态变更处理类型异常: {}", JSON.toJSONString(event));
                        break;
                }
            } catch (Exception e) {
                log.error("行为状态变更实现类JSON转换异常: {}", ExceptionUtil.getStackStr(e));
            }
        }
        if (!updateMap.isEmpty()) {
            Iterator<Map.Entry<String, List<DeviceDO>>> iterator = updateMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, List<DeviceDO>> next = iterator.next();
                List<DeviceDO> value = next.getValue();
                deviceMapper.batchUpdateDevice(value);
            }
        }
    }
}
